//
//  XGL_MessageChatViewController.swift
//  XGamesLive
//
//  Created by ios on 2024/5/27.
//

import UIKit
import TZImagePickerController

class XGL_MessageChatViewController: UIViewController,CustomNavgationBar{
    typealias HandleBlock = ()->Void
    typealias RefreshBlock = ()->Void
    var navView: UIView!
    lazy var hudView: XGL_CustomHudView = XGL_CustomHudView()
    lazy var giftPickerView = XGL_GiftListBarView()
    lazy var animationView = XGL_GiftAnimationView()
    var inputBarView: XGL_MessageChatInputView!
    var tableView: UITableView!
    var messageDatas: [XGL_MessageChatData] = []
    private var userData: CompleteInfor?
    
    var userId: String = ""
    var userName: String = ""
    var userHead: String = ""
    var blackHandler: HandleBlock?
    var refreshBlock: RefreshBlock?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        self.createCustomBackgroundView()
        self.createXglView()
        self.getGiftDatasRequest()
        self.getuserDataRequest()
        let cacheData = ChatMessageCacheManager.shared.infor
        if let datas = cacheData.conversations[self.userId] {
            self.messageDatas = datas
            self.tableView.reloadData {
                self.tableView.scrollToRow(at: IndexPath(row: datas.count - 1, section: 0), at: .bottom, animated: false)
            }
        }
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        self.creatClearNavigationBar(title: self.userName)
    }
    
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        self.navView.removeFromSuperview()
    }
}

extension XGL_MessageChatViewController{
    func reloadMessageData(message: XGL_MessageChatData?){
        if let lastItem = self.messageDatas.last,let date1 = lastItem.time.stringToDate(),let date2 = message?.time.stringToDate() {
            if abs(date1.timeIntervalSince(date2)) > (5 * 60){
                let timeMessage = XGL_MessageChatData(userId: self.userId,header: XGL_userDataManager.share.userHeader,name: XGL_userDataManager.share.userName,time: NSInteger(Date().timeIntervalSince1970 * 1000).description,messageType: 4)
                self.messageDatas.append(timeMessage)
            }
        }
        if let messageData = message{
            self.messageDatas.append(messageData)
        }
        self.tableView.reloadData(){
            self.tableView.scrollToRow(at: IndexPath(row: self.messageDatas.count - 1, section: 0), at: .bottom, animated: false)
        }
        let cacheData = ChatMessageCacheManager.shared.infor
        cacheData.conversations[self.userId] = self.messageDatas
        ChatMessageCacheManager.shared.saveInfor(inforData: cacheData)
        if let block = self.refreshBlock {
            block()
        }
    }
}

extension XGL_MessageChatViewController{
    @objc private func moreItemAction(){
        let actionController = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
        let action = UIAlertAction(title: "Report", style: .default) { _ in
            if let infor = self.userData {
                let vc = XGL_ReportReasonViewController()
                vc.id = infor.id
                self.navigationController?.pushViewController(vc)
            }
        }
        let action1 = UIAlertAction(title: "Block", style: .default) { _ in
            self.alertPicker(message: "Whether to blocklist him ？") { [weak self] in
                guard let `self` = self else { return }
                self.addBlacklistRequest()
            }
        }
        
        let action2 = UIAlertAction(title: "Cancel", style: .cancel)
        actionController.addAction(action)
        actionController.addAction(action1)
        actionController.addAction(action2)
        self.present(actionController, animated: true)
    }
    
    @objc private func photoItemAction(){
        self.openCamera()
        let authStatus = AVCaptureDevice.authorizationStatus(for: .video)
        guard authStatus == .authorized else {
            let actionController = UIAlertController(title: "Warm reminder", message: "Please open camera permissions", preferredStyle: .alert)
            let action3 = UIAlertAction(title: "Sure", style: .default) { _ in
                if let url = URL(string: UIApplication.openSettingsURLString){
                    UIApplication.shared.open(url)
                }
            }
            let action2 = UIAlertAction(title: "Cancel", style: .cancel)
            actionController.addAction(action2)
            actionController.addAction(action3)
            self.present(actionController, animated: true)
            return
        }
        if UIImagePickerController.isSourceTypeAvailable(.camera) {
            let imagePicker = UIImagePickerController()
            imagePicker.delegate = self
            imagePicker.sourceType = .camera
            imagePicker.allowsEditing = false
            self.present(imagePicker, animated: true, completion: nil)
        }
    }
    
    @objc private func imageItemAction(){
        let imagePick = TZImagePickerController(maxImagesCount: 1, delegate: self)
        imagePick?.allowCrop = false
        imagePick?.maxImagesCount = 1
        imagePick?.allowTakeVideo = false
        imagePick?.modalPresentationStyle = .fullScreen
        UIBarButtonItem.appearance().setTitleTextAttributes([NSAttributedString.Key.font: UIFont.pingfangSC_Semibold(fontSize: 15),NSAttributedString.Key.foregroundColor: UIColor.hexColor("#80FFE6")], for: UIControl.State.normal)
        self.present(imagePick!, animated: true, completion: nil)
    }
    
    @objc private func videoItemAction(){
        let imagePick = TZImagePickerController(maxImagesCount: 1, delegate: self)
        imagePick?.allowCrop = false
        imagePick?.maxImagesCount = 1
        imagePick?.allowPickingVideo = true
        imagePick?.allowPickingImage = false
        imagePick?.allowPickingGif = false
        imagePick?.modalPresentationStyle = .fullScreen
        UIBarButtonItem.appearance().setTitleTextAttributes([NSAttributedString.Key.font: UIFont.pingfangSC_Semibold(fontSize: 15),NSAttributedString.Key.foregroundColor: UIColor.hexColor("#80FFE6")], for: UIControl.State.normal)
        self.present(imagePick!, animated: true, completion: nil)
    }
    @objc private func giftItemAction(){
        self.selectGiftItem()
    }
    
    @objc private func sendTextAction(){
        if let text = self.inputBarView.inputTextView.text,text.isEmpty == false {
            self.validationSensitiveWordRequest(content: text) { [weak self] in
                self?.inputBarView.restoreInitialization()
                let messageData = XGL_MessageChatData(userId: self?.userId ?? "",header: XGL_userDataManager.share.userHeader,name: XGL_userDataManager.share.userName,time: NSInteger(Date().timeIntervalSince1970 * 1000).description,content: text,messageType: 0)
                self?.reloadMessageData(message: messageData)
            }
        }
    }
}

extension XGL_MessageChatViewController{
    func openCamera() {
        let authStatus = AVCaptureDevice.authorizationStatus(for: .video)
        if authStatus == .notDetermined {
            AVCaptureDevice.requestAccess(for: .video) { (res) in
                
            }
        }
    }
    func selectGiftItem(){
        if self.inputBarView.inputTextView.isFirstResponder{
            self.inputBarView.inputTextView.resignFirstResponder()
        }
        self.view.addSubview(self.giftPickerView)
        self.giftPickerView.snp.makeConstraints { make in
            make.edges.equalToSuperview()
        }
        self.giftPickerView.showGiftPickerView { selectGift in
            self.sendGiftRequest(giftData: selectGift)
        }
    }
}

extension XGL_MessageChatViewController{
    private func alertPicker(message: String,handler:@escaping ()->Void){
        let actionController = UIAlertController(title: "Warm reminder", message: message, preferredStyle: .alert)
        let action3 = UIAlertAction(title: "Sure", style: .default) { _ in
            handler()
        }
        let action2 = UIAlertAction(title: "Cancel", style: .cancel)
        actionController.addAction(action2)
        actionController.addAction(action3)
        self.present(actionController, animated: true)
    }
    
    func getVideoCoverImage(videoURL: URL) -> Data? {
        let asset = AVAsset.init(url: videoURL)
        let assetImgGenerate = AVAssetImageGenerator(asset: asset)
        assetImgGenerate.appliesPreferredTrackTransform = true
        let time = CMTimeMakeWithSeconds(1.0, preferredTimescale: 600)
        
        do {
            let img = try assetImgGenerate.copyCGImage(at: time, actualTime: nil)
            let image = UIImage(cgImage: img)
            return image.jpegData(compressionQuality: 1.0)
        } catch {
            print(error.localizedDescription)
        }
        return nil
    }
}

extension XGL_MessageChatViewController: UIImagePickerControllerDelegate,UINavigationControllerDelegate{
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        if let selectImage = info[.originalImage] as? UIImage {
            let messageData = XGL_MessageChatData(userId: self.userId,header: XGL_userDataManager.share.userHeader,name: XGL_userDataManager.share.userName, time: NSInteger(Date().timeIntervalSince1970 * 1000).description,cover: selectImage.jpegData(compressionQuality: 1.0), messageType: 1,status: 0)
            self.reloadMessageData(message: messageData)
            self.uploadImagesRequest(image: selectImage) { [weak self] url in
                if let index = self?.messageDatas.firstIndex(where: {$0.messageId == messageData.messageId}){
                    self?.messageDatas[index].status = 2
                    self?.reloadMessageData(message: nil)
                }
            }
        }
        picker.dismiss(animated: true, completion: nil)
    }
    
    func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
        picker.dismiss(animated: true, completion: nil)
    }
}

extension XGL_MessageChatViewController:TZImagePickerControllerDelegate{
    
    func imagePickerController(_ picker: TZImagePickerController!, didFinishPickingPhotos photos: [UIImage]!, sourceAssets assets: [Any]!, isSelectOriginalPhoto: Bool) {
        if let selectImage = photos.first {
            let messageData = XGL_MessageChatData(userId: self.userId,header: XGL_userDataManager.share.userHeader,name: XGL_userDataManager.share.userName, time: NSInteger(Date().timeIntervalSince1970 * 1000).description,cover: selectImage.jpegData(compressionQuality: 1.0), messageType: 1,status: 0)
            self.reloadMessageData(message: messageData)
            self.uploadImagesRequest(image: selectImage) { [weak self] url in
                if let index = self?.messageDatas.firstIndex(where: {$0.messageId == messageData.messageId}){
                    self?.messageDatas[index].status = 2
                    self?.reloadMessageData(message: nil)
                }
            }
        }
        
    }
    
    func imagePickerController(_ picker: TZImagePickerController!, didFinishPickingVideo coverImage: UIImage!, sourceAssets asset: PHAsset!) {
        if asset.mediaType == .video {
            PHCachingImageManager().requestAVAsset(forVideo: asset, options: nil) { asset1, audioMix, info in
                DispatchQueue.main.async {
                    if let urlAsset = asset1 as? AVURLAsset {
                        print("video url：\(urlAsset.url)")
                        print("video duration:\(urlAsset.duration)s")
                        do {
                            let data = try Data(contentsOf: urlAsset.url)
                            let messageData = XGL_MessageChatData(userId: self.userId,header: XGL_userDataManager.share.userHeader,name: XGL_userDataManager.share.userName, time: NSInteger(Date().timeIntervalSince1970 * 1000).description,cover: self.getVideoCoverImage(videoURL: urlAsset.url),videoPath: urlAsset.url, messageType: 2,status: 0)
                            self.reloadMessageData(message: messageData)
                            self.uploadVideoRequest(video: data) { [weak self] url in
                                if let index = self?.messageDatas.firstIndex(where: {$0.messageId == messageData.messageId}){
                                    self?.messageDatas[index].status = 2
                                    self?.reloadMessageData(message: nil)
                                }
                            }
                        } catch  {
                            debugPrint(error)
                        }
                        
                    }
                }
                
            }
        }
    }
    
}

extension XGL_MessageChatViewController{
    
    private func getuserDataRequest(){
        PanRequestManager<XGL_RequestBaseResponse<CompleteInfor>,XGL_CustomRequestError>().request(XGLPersonalRequestAPI(requestAPI: .userData(userId: self.userId))) { result in
            switch result{
            case .success(let response):
                if let result = response.resultData {
                    self.userData = result
                }
                break
            default:
                break
            }
        }
    }
    private func uploadImagesRequest(image: UIImage,complete: ((_ url: String)->Void)? = nil){
        PanRequestManager<XGL_RequestBaseResponse<Response>,XGL_CustomRequestError>().request(CustomRequestAPI(requestAPI: .Upload(image: image, file: "file"))) { result in
            switch result{
            case .success(let response):
                if let block = complete {
                    block(response.resultJson)
                }
                break
            default:
                break
            }
        }
    }
    
    private func uploadVideoRequest(video: Data,complete: ((_ url: String)->Void)? = nil){
        PanRequestManager<XGL_RequestBaseResponse<VideoUploadResult>,XGL_CustomRequestError>().request(CustomRequestAPI(requestAPI: .UploadVideo(video: video))) { result in
            switch result{
            case .success(let response):
                if let data = response.resultData{
                    if let block = complete {
                        block(data.coverPath)
                    }
                }
                break
            default:
                break
            }
        }
    }
    
    func sendGiftRequest(giftData: GiftData){
        self.hudView.hudView.backgroundColor = .clear
        self.hudView.hudView.startAnimation()
        self.view.addSubview(self.hudView)
        self.hudView.snp.makeConstraints { make in
            make.width.centerX.bottom.equalToSuperview()
            make.top.equalTo(PanNavibarH)
        }
        PanRequestManager<XGL_RequestBaseResponse<SendGiftResult>,XGL_CustomRequestError>().request(CustomRequestAPI(requestAPI: .SendGift(giftId: giftData.id, userId: self.userId))) { result in
            self.hudView.dismiss()
            switch result{
            case .success(let response):
                if let data = response.resultData {
                    self.giftPickerView.coin = data.amount
                    if data.enough == 0{
                        MXProgressHUD.hudWithText("Gift failure")
                    }else if data.enough == 2{
                        MXProgressHUD.hudWithText("Your balance is insufficient, please top it up")
                    }
                    if data.enough > 0{
                        let messageData = XGL_MessageChatData(userId: self.userId,header: XGL_userDataManager.share.userHeader,name: XGL_userDataManager.share.userName, time: NSInteger(Date().timeIntervalSince1970 * 1000).description,content: "You presented \(giftData.name) to \(self.userName)",cover: nil, messageType: 3)
                        self.reloadMessageData(message: messageData)
                        
                        self.animationView.showGiftAnimation(message: "\(self.userName) received a gift from \(XGL_userDataManager.share.userName)", giftData: giftData)
                    }
                }
                break
            default:
                break
            }
        }
    }
    
    func addBlacklistRequest(){
        self.hudView.hudView.backgroundColor = .clear
        self.hudView.hudView.startAnimation()
        self.view.addSubview(self.hudView)
        self.hudView.snp.makeConstraints { make in
            make.width.centerX.bottom.equalToSuperview()
            make.top.equalTo(PanNavibarH)
        }
        PanRequestManager<XGL_RequestBaseResponse<SendGiftResult>,XGL_CustomRequestError>().request(XGLPersonalRequestAPI(requestAPI: .AddBlacklist(userId: self.userId))) { result in
            self.hudView.dismiss()
            switch result{
            case .success(let response):
                XGL_Notice.default.post(name: XGL_Notification.addBlack.notificationName, object: nil)
                MXProgressHUD.hudWithText("Submit successfully") {
                    self.navigationController?.popViewController()
                    if let block = self.blackHandler {
                        block()
                    }
                }
                break
            default:
                break
            }
        }
    }
    
    private func getGiftDatasRequest(){
        PanRequestManager<XGL_RequestBaseResponse<PageModel<GiftData>>,XGL_CustomRequestError>().request(CustomRequestAPI(requestAPI: .Gifts)) { result in
            switch result{
            case .success(let response):
                if let data = response.resultData {
                    self.giftPickerView.giftSource = data.data
                }
                break
            default:
                break
            }
        }
    }
    
    private func validationSensitiveWordRequest(content: String,complete: @escaping ()->Void){
        PanRequestManager<XGL_RequestBaseResponse<Response>,XGL_CustomRequestError>().request(XGLMessageRequestAPI(requestAPI: .ValidationSensitiveWord(content: content))) { result in
            switch result{
            case .success:
                complete()
                break
            default:
                break
            }
        }
    }
}

extension XGL_MessageChatViewController: UITableViewDelegate,UITableViewDataSource{
    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return self.messageDatas.count
    }
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let model = self.messageDatas[indexPath.row]
        if model.messageType == 0{
            let cell = tableView.dequeueReusableCell(withClass: XGL_MessageChatTextTableViewCell.self)
            cell.itemData = model
            return cell
        }else if model.messageType == 1 || model.messageType == 2{
            let cell = tableView.dequeueReusableCell(withClass: XGL_MessageChatImageTableViewCell.self)
            cell.itemData = model
            return cell
        }else{
            let cell = tableView.dequeueReusableCell(withClass: XGL_MessageChatNormalTableViewCell.self)
            if model.messageType == 3{
                cell.itemText.text = model.content
            }else{
                if let date = model.time.stringToDate() {
                    if date.isToday{
                        cell.itemText.text = date.toFormat("HH:mm")
                    }else{
                        cell.itemText.text = date.toFormat("MM-dd HH:mm")
                    }
                }
            }
            
            return cell
        }
        
    }
}

extension XGL_MessageChatViewController{
    private func createXglView(){
        self.tableView = UITableView().then({ make in
            make.register(cellWithClass: XGL_MessageChatTextTableViewCell.self)
            make.register(cellWithClass: XGL_MessageChatImageTableViewCell.self)
            make.register(cellWithClass: XGL_MessageChatNormalTableViewCell.self)
            make.dataSource = self
            make.delegate = self
            make.backgroundColor = UIColor.clear
            make.rowHeight = UITableView.automaticDimension
            make.estimatedRowHeight = 150
            make.separatorStyle = .none
        })
        self.inputBarView = XGL_MessageChatInputView().then({ make in
            make.sendItem.addTarget(self, action: #selector(self.sendTextAction), for: .touchUpInside)
            make.moreItemsView.photoItem.addTarget(self, action: #selector(self.photoItemAction), for: .touchUpInside)
            make.moreItemsView.imageItem.addTarget(self, action: #selector(self.imageItemAction), for: .touchUpInside)
            make.moreItemsView.videoItem.addTarget(self, action: #selector(self.videoItemAction), for: .touchUpInside)
            make.moreItemsView.giftItem.addTarget(self, action: #selector(self.giftItemAction), for: .touchUpInside)
        })
        self.view.addSubview(self.tableView)
        self.view.addSubview(self.inputBarView)
        self.view.addSubview(self.animationView)
        
        self.tableView.snp.makeConstraints { make in
            make.width.centerX.equalToSuperview()
            make.bottom.equalTo(self.inputBarView.snp.top)
            make.top.equalTo(PanNavibarH)
        }
        self.inputBarView.snp.makeConstraints { make in
            make.width.centerX.bottom.equalToSuperview()
        }
        
        self.animationView.snp.makeConstraints { make in
            make.centerX.width.equalToSuperview()
            make.height.equalTo(50.0)
            make.top.equalTo(PanNavibarH + 5.0)
        }
    }
    
    func creatClearNavigationBar(title: String) {
        guard let window = UIApplication.shared.currentWindow else { return  }
        self.navigationController?.navigationBar.barStyle = .default
        setNeedsStatusBarAppearanceUpdate()
        let backColor = UIColor.clear
        let imageIcon = imageWithName("icon_xgl_back_white")
        
        navView = UIView().then { make in
            make.backgroundColor = backColor
        }
        let backItem = MXCustomButton().then { make in
            make.setImage(imageIcon, for: .normal)
            make.buttonSelectAction { [weak self] in
                guard let `self` = self else { return }
                self.backAction()
            }
        }
        let titleView = UILabel().then { make in
            make.textColor = UIColor.white
            make.font = UIFont.pingfangSC_Regular(fontSize: 18.0)
            make.text = title
        }
        let rightItem = UIButton().then { make in
            make.setImage(imageWithName("icon_more_white"), for: .normal)
            make.addTarget(self, action: #selector(self.moreItemAction), for: .touchUpInside)
        }
        navView.addSubview(backItem)
        navView.addSubview(titleView)
        navView.addSubview(rightItem)
        window.addSubview(navView)
        backItem.snp.makeConstraints { make in
            make.left.equalTo(5.0)
            make.width.height.equalTo(50.0)
            make.bottom.equalTo(-3.0)
        }
        titleView.snp.makeConstraints { make in
            make.centerX.equalToSuperview()
            make.centerY.equalTo(backItem)
        }
        rightItem.snp.makeConstraints { make in
            make.centerY.equalTo(backItem)
            make.right.equalTo(-12.0)
            make.width.height.equalTo(26.0)
        }
        navView.snp.makeConstraints { make in
            make.centerX.top.equalToSuperview()
            make.width.equalTo(ScreenWidth)
            make.height.equalTo(PanNavibarH)
        }
    }
}
